package org.lop.modules.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

/**
 * Properties工具.
 * 
 * 可载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的值, 但以System的Property优先.
 * 
 * @author 潘瑞峥
 * @date 2013-6-1
 */
public class PropertiesLoader {

	private static Logger logger = LoggerFactory.getLogger( PropertiesLoader.class );

	private static ResourceLoader resourceLoader = new DefaultResourceLoader();

	private final Properties properties;

	public PropertiesLoader( String... resourcesPaths ) {
		properties = loadProperties( resourcesPaths );
	}

	public Properties getProperties() {
		return properties;
	}

	/**
	 * 载入多个文件, 文件路径使用Spring Resource格式.
	 */
	private Properties loadProperties( String... resourcesPaths ) {
		Properties properties = new Properties();

		for ( String location : resourcesPaths ) {
			logger.debug( "Loading properties file from path: {}", location );

			InputStream is = null;
			try {
				Resource resource = resourceLoader.getResource( location );
				is = resource.getInputStream();
				properties.load( is );
			} catch ( IOException ex ) {
				logger.info( "Could not load properties from path: {}, {} ", location, ex.getMessage() );
			} finally {
				IOUtils.closeQuietly( is );
			}
		}
		return properties;
	}

	private String getValue( String key ) {
		String systemProperty = System.getProperty( key );
		if ( null != systemProperty ) {
			return systemProperty;
		}
		return properties.getProperty( key );
	}

	public String getProperty( String key ) {
		String value = getValue( key );
		if ( null == value ) {
			throw new NoSuchElementException();
		}
		return value;
	}

	public String getProperty( String key, String defaultValue ) {
		String value = getValue( key );
		return ( null != value ) ? value : defaultValue;
	}

	public Integer getInteger( String key ) {
		String value = getValue( key );
		if ( null == value ) {
			throw new NoSuchElementException();
		}
		return Integer.valueOf( value );
	}

	public Integer getInteger( String key, Integer defaultValue ) {
		String value = getValue( key );
		return ( null != value ) ? Integer.valueOf( value ) : defaultValue;
	}

	public Double getDouble( String key ) {
		String value = getValue( key );
		if ( null == value ) {
			throw new NoSuchElementException();
		}
		return Double.valueOf( value );
	}

	public Double getDouble( String key, Integer defaultValue ) {
		String value = getValue( key );
		return ( null != value ) ? Double.valueOf( value ) : defaultValue;
	}

	public Boolean getBoolean( String key ) {
		String value = getValue( key );
		if ( null == value ) {
			throw new NoSuchElementException();
		}
		return Boolean.valueOf( value );
	}

	public Boolean getBoolean( String key, boolean defaultValue ) {
		String value = getValue( key );
		return ( null != value ) ? Boolean.valueOf( value ) : defaultValue;
	}

}